home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / tsm23s.lha / OpalLoad.c < prev    next >
C/C++ Source or Header  |  1993-10-08  |  37KB  |  1,202 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. //    $Author: M_J_Paddock $
  21. //    $Date: 1992/08/08 01:09:24 $
  22. //    $Revision: 1.5 $
  23.  
  24. // Include precompiled headers if required
  25. #ifndef TSMORPH_H
  26. #include "TSMorph.h"
  27. #endif
  28.  
  29. #include "JPEG_LS/jinclude.h"
  30.  
  31. extern UWORD FileFormat = 0;    // Format of file being loaded
  32.  
  33. /* Loads an image (in various formats)
  34.  * pic     : pointer to Picture structure
  35.  * filename: filename to load
  36.  * Returns : TRUE if loaded OK
  37.  */
  38. BOOL
  39. MyLoadBrush (struct Picture *pic,UBYTE *filename) {
  40.     BOOL OpenILBM = FALSE;    // Are we loading a (<24 plane) ILBM
  41.     char *e = NULL;            // First
  42.     char *e1 = NULL;            // and second part of error message
  43.     long hnum;                    // Help number
  44.     long err;                    // Error flag
  45.     BPTR fh;                        // File handle
  46.     UBYTE buffer[5]="\0\0\0\0";    // First 4 bytes of file for identification
  47.  
  48.     // Try and open file and read 1st 4 bytes
  49.     if (fh = Open(filename,MODE_OLDFILE)) {
  50.         FRead(fh,buffer,4,1);
  51.         // check if a sort of IFF file
  52.         if (!strcmp(buffer,"LIST") ||
  53.              !strcmp(buffer,"CAT ") ||
  54.              !strcmp(buffer,"FORM")) {
  55.             FileFormat = FORMAT_IFF;
  56.         }
  57.         else {
  58.             // check if a JFIF JPEG
  59.             if ((buffer[0] == 0xFF) &&
  60.                  (buffer[1] == 0xD8)) {
  61.                 FileFormat = FORMAT_JPEG;
  62.             }
  63.             else {
  64.                 // check if a GIF
  65.                 if ((buffer[0] == 'G') &&
  66.                      (buffer[1] == 'I') &&
  67.                      (buffer[2] == 'F')) {
  68.                     FileFormat = FORMAT_GIF;
  69.                 }
  70.                 else {
  71.                     // check if a PPM
  72.                     if ((buffer[0] == 'P') &&
  73.                          ((buffer[1] == '2') ||
  74.                           (buffer[1] == '3') ||
  75.                           (buffer[1] == '5') ||
  76.                           (buffer[1] == '6'))) {
  77.                         FileFormat = FORMAT_PPM;
  78.                     }
  79.                     else {
  80.                         // Otherwise default to TARGA (the only other format we load)
  81.                         FileFormat = FORMAT_TARGA;
  82.                     }
  83.                 }
  84.             }
  85.         }
  86.         Close(fh);
  87.     }
  88.     else {
  89.         // error file not found
  90.         FileFormat = 0;
  91.         e = "File does not exist '%s'";
  92.         hnum = HE_NoFile;
  93.         e1 = filename;
  94.     }
  95.     // If the file is and IFF and we only open ILBMs in some cases then perform some checks
  96.     if ((FileFormat == FORMAT_IFF) && ((OpenMode == OPEN_ILBM_IF_ILBM) || (OpenMode == OPEN_ILBM_IF_COLOURS))) {
  97.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  98.             err = queryilbm(pic->ilbm,filename);
  99.             if (!err) {
  100.                 if (OpenMode == OPEN_ILBM_IF_COLOURS) {
  101.                     // if we only open if screen colours then check depth
  102.                     if (!(pic->ilbm->Bmhd.nPlanes > TSMorphWnd->WScreen->BitMap.Depth)) {
  103.                         OpenILBM = TRUE;
  104.                     }
  105.                 }
  106.                 else {    // OpenMode == OPEN_ILBM_IF_ILBM
  107.                     // if open if an ILBM then check < 24 bits
  108.                     if (pic->ilbm->Bmhd.nPlanes < 24) {
  109.                         OpenILBM = TRUE;
  110.                     }
  111.                 }
  112.             }
  113.             FreeIFF(pic->ilbm->ParseInfo.iff);
  114.             pic->ilbm->ParseInfo.iff = NULL;
  115.         }
  116.         else {
  117.             e = "Unable to AllocIFF";
  118.             hnum = HE_AllocIFF;
  119.         }
  120.     }
  121.     // If we always open ILBM or the above checks out OK then try and open
  122.     if (OpenILBM || ((OpenMode == OPEN_ILBM_ALWAYS) && !e)) {
  123.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  124.             // set up IFF stuff and load image
  125.             pic->ilbm->ParseInfo.propchks = props;
  126.             pic->ilbm->ParseInfo.collectchks = nowt;
  127.             pic->ilbm->ParseInfo.stopchks = stops;
  128.             if (loadbrush(pic->ilbm,filename)) {
  129.                 closeifile(&(pic->ilbm->ParseInfo));
  130.                 e = "Failure loading Image '%s'";
  131.                 e1 = filename;
  132.                 hnum = HE_LoadImage;
  133.             }
  134.             else {
  135.                 closeifile(&(pic->ilbm->ParseInfo));
  136.                 FreeIFF(pic->ilbm->ParseInfo.iff);
  137.                 pic->ilbm->ParseInfo.iff = NULL;
  138.                 return TRUE;
  139.             }
  140.         }
  141.         else {
  142.             e = "Unable to AllocIFF";
  143.             hnum = HE_AllocIFF;
  144.         }
  145.     }
  146.     else {
  147.         // otherwise try and load using another format
  148.         if (!e) {
  149.             return OpalLoad(pic,filename);
  150.         }
  151.     }
  152.     Error(e,"OK",e1,hnum);
  153.     return FALSE;
  154. }
  155.  
  156. /* Loads an image (in various formats)
  157.  * pic     : pointer to Picture structure
  158.  * filename: filename to load
  159.  * Returns : TRUE if loaded OK
  160.  */
  161. BOOL OpalLoad(struct Picture *pic,UBYTE *filename) {
  162.     char                     *e        = NULL;    // Error message main text
  163.     char                    *e1     = NULL;    // sub text,
  164.     long                     Err;                // OpalError
  165.     ULONG                    hnum;                // Help on error
  166.     struct OpalScreen    *OScrn;            // OpalScreen
  167.     UBYTE                    *p[3]= {NULL,NULL,NULL};    // rbg planes
  168.     UBYTE r[256],g[256],b[256];        // rgb colors of screen (8 bit)
  169.     UWORD                    i;                    // loop counter
  170.     UWORD                 color;            // Colour
  171.     UBYTE *red,*green,*blue;            // rgb pointers
  172.     UWORD                    maxcol;            // Number of colors
  173.     UWORD xadd;                                // bytes to add to get to next line
  174.     decompress_info_ptr info;            // Load JPEG stuff
  175.     BOOL                    ReMap = FALSE;    // Have to remap ourselves
  176.     struct RastPort    Rp;                // Rast port for conversion
  177.     struct DCTVCvtHandle    *handle=NULL;    // DCTV conversion stuff
  178.     UWORD                    *DCTVcolors=NULL;    // DCTV palette
  179.  
  180.     OpenProgressWindow();        // Open the progress window
  181.     if (ProgressWnd) {
  182.          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  183.                               GTTX_Text,(ULONG)"Creating Colormap",
  184.                              TAG_END);
  185.         HandleProgressIDCMP();
  186.     }
  187.     // Store and set up to 256 colours
  188.       maxcol = min((1 << TSMorphWnd->WScreen->BitMap.Depth),256);
  189.     for (i=0; i < maxcol; ++i) {
  190.         color = GetRGB4(TSMorphWnd->WScreen->ViewPort.ColorMap,i);
  191.         r[i]=((color&0x0f00)>>4)|((color&0x0f00)>>8);
  192.         g[i]=(color&0x00f0)|((color&0x00f0)>>4);
  193.         b[i]=((color&0x000f)<<4)|(color&0x000f);
  194.     }
  195.     // If we are not opening OPAL and the file is IFF
  196.     if ((OpenMode != OPEN_OPAL) &&
  197.          (FileFormat == FORMAT_IFF)) {
  198.         // try and load IFF
  199.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  200.             pic->ilbm->ParseInfo.propchks = props;
  201.             pic->ilbm->ParseInfo.collectchks = nowt;
  202.             pic->ilbm->ParseInfo.stopchks = stops;
  203.             if (ProgressWnd) {
  204.                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  205.                                       GTTX_Text,(ULONG)"Loading ILBM",
  206.                                      TAG_END);
  207.                 HandleProgressIDCMP();
  208.             }
  209.             if (loadbrush(pic->ilbm,filename)) {
  210.                 closeifile(&(pic->ilbm->ParseInfo));
  211.                 e = "Failure loading Image '%s'";
  212.                 e1 = filename;
  213.                 hnum = HE_LoadImage;
  214.             }
  215.             else {
  216.                 closeifile(&(pic->ilbm->ParseInfo));
  217.                 if (pic->ilbm->Bmhd.nPlanes == 24) {
  218.                     // 24 bit image - free colours
  219.                     freecolors(pic->ilbm);
  220.                     if (ProgressWnd) {
  221.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  222.                                               GTTX_Text,(ULONG)"Converting 24 bit to Chunky",
  223.                                              TAG_END);
  224.                         HandleProgressIDCMP();
  225.                     }
  226.                     // Allocate Chunky planes
  227.                     if ((p[0] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  228.                          (p[1] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  229.                          (p[2] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0))) {
  230.                         // Convert to chunky RGB
  231.                         if (InitArray(pic->ilbm->Bmhd.w) && PlanarToChunky(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0],p[1],p[2])) {
  232.                             // Bytes to add to get to next row
  233.                             xadd = (((pic->ilbm->Bmhd.w+15)>>4)<<4) - pic->ilbm->Bmhd.w;
  234.                             red = p[0];
  235.                             blue = p[2];
  236.                             green = p[1];
  237.                             if (ProgressWnd) {
  238.                                 GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  239.                                                        GTTX_Text,(ULONG)"Remapping 24 bit palette",
  240.                                                       TAG_END);
  241.                                 GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  242.                                                      GTSL_Level,0,
  243.                                                       GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  244.                                 HandleProgressIDCMP();
  245.                              }
  246.                              // Convert to screen palette using 020 if present
  247.                             if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  248.                                 RGBToScreen020(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  249.                             }
  250.                              else {
  251.                                 RGBToScreen000(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  252.                             }
  253.                             if (ProgressWnd) {
  254.                                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  255.                                                         GTTX_Text,(ULONG)"Converting 24 bit to Planar",
  256.                                                        TAG_END);
  257.                                 HandleProgressIDCMP();
  258.                             }
  259.                             // Convert back to planar
  260.                             if (ChunkyToPlanar(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0])) {
  261.                                 // Free everything and return ok
  262.                                 FreeArray();
  263.                                 FreeVec(p[0]);
  264.                                 FreeVec(p[1]);
  265.                                 FreeVec(p[2]);
  266.                                 CloseProgressWindow();
  267.                                 return TRUE;
  268.                             }
  269.                             // Free everything
  270.                             else {
  271.                                 e = "Unable to allocate memory for bitmap";
  272.                                 hnum = HE_AllocPlanes;
  273.                             }
  274.                         }
  275.                         else {
  276.                             e = "Unable to allocate memory for bitmap";
  277.                             hnum = HE_AllocPlanes;
  278.                         }
  279.                         FreeArray();
  280.                     }
  281.                     else {
  282.                         e = "Unable to allocate memory for bitmap";
  283.                         hnum = HE_AllocPlanes;
  284.                     }
  285.                     if (p[0]) FreeVec(p[0]);
  286.                     if (p[1]) FreeVec(p[1]);
  287.                     if (p[2]) FreeVec(p[2]);
  288.                 }
  289.                 else {
  290.                     // not a 24 bit image
  291.                     // If we have dctv.library then check if a DCTV image
  292.                     if (DCTVBase && TestDCTVSignature(pic->ilbm->brbitmap)) {
  293.                         if (ProgressWnd) {
  294.                              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  295.                                                   GTTX_Text,(ULONG)"Converting DCTV to Chunky",
  296.                                                  TAG_END);
  297.                             HandleProgressIDCMP();
  298.                         }
  299.                         // Allocate and set up DCTV palette
  300.                         if (DCTVcolors = AllocVec(2L<<pic->ilbm->Bmhd.nPlanes,NULL)) {
  301.                             for (i=0; i < (1L<<pic->ilbm->Bmhd.nPlanes); ++i) {
  302.                                 DCTVcolors[i] = ((pic->ilbm->RGB[i*4+1] & 0xf0) << 4) |
  303.                                                      ((pic->ilbm->RGB[i*4+2] & 0xf0)) |
  304.                                                      ((pic->ilbm->RGB[i*4+3] & 0xf0) >> 4);
  305.                             }
  306.                             // Allocate RGB chunky planes and DCTV stuff
  307.                             if ((p[0] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  308.                                  (p[1] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  309.                                  (p[2] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  310.                                  (InitArray(pic->ilbm->Bmhd.w)) &&
  311.                                  (handle = AllocDCTVCvtTags(pic->ilbm->brbitmap,
  312.                                                     DCTVCVTA_Type, DCTVCVTT_DCTVtoRGB,
  313.                                                     DCTVCVTA_Width, (((pic->ilbm->Bmhd.w+15)>>4)<<4),
  314.                                                     DCTVCVTA_Height, pic->ilbm->Bmhd.h,
  315.                                                     DCTVCVTA_Flags, ((pic->ilbm->camg & LACE)?DCTVCVTF_Lace:0)|
  316.                                                                         DCTVCVTF_CustomRGBBuf,
  317.                                                     DCTVCVTA_ColorTable, DCTVcolors,
  318.                                                     TAG_END))) {
  319.                                 handle->Red = p[0];
  320.                                 handle->Green = p[1];
  321.                                 handle->Blue = p[2];
  322.                                 if (ProgressWnd) {
  323.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  324.                                                         GTSL_Level,0,
  325.                                                          GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  326.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass1],ProgressWnd,NULL,
  327.                                                      GTSL_Level,1,
  328.                                                       GTSL_Max,2,TAG_END);
  329.                                     HandleProgressIDCMP();
  330.                                 }
  331.                                 // use dctv.library to convert to chunky
  332.                                 while (handle->DstLineNum < handle->Height) {
  333.                                     CvtDCTVLine(handle);
  334.                                     if ((handle->DstLineNum > 0) &&
  335.                                          (handle->DstLineNum <= handle->Height)) {
  336.                                         if (ProgressWnd) {
  337.                                                GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  338.                                                         GTSL_Level,handle->DstLineNum-1,
  339.                                                         TAG_END);
  340.                                             HandleProgressIDCMP();
  341.                                         }
  342.                                         handle->Red += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  343.                                         handle->Green += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  344.                                         handle->Blue += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  345.                                     }
  346.                                 }
  347.                                 if (ProgressWnd) {
  348.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  349.                                                           GTTX_Text,(ULONG)"Remapping DCTV palette",
  350.                                                        TAG_END);
  351.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass1],ProgressWnd,NULL,
  352.                                                      GTSL_Level,2,
  353.                                                        TAG_END);
  354.                                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  355.                                                         GTSL_Level,0,
  356.                                                        TAG_END);
  357.                                   }
  358.                                   // convert to screen palette and then to planar (see above)
  359.                                 xadd = (((pic->ilbm->Bmhd.w+15)>>4)<<4) - pic->ilbm->Bmhd.w;
  360.                                 red = p[0];
  361.                                 blue = p[2];
  362.                                 green = p[1];
  363.                                 if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  364.                                     RGBToScreen020(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  365.                                 }
  366.                                  else {
  367.                                     RGBToScreen000(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  368.                                 }
  369.                                 if (ProgressWnd) {
  370.                                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  371.                                                           GTTX_Text,(ULONG)"Converting to Planar",
  372.                                                            TAG_END);
  373.                                     HandleProgressIDCMP();
  374.                                 }
  375.                                 if (ChunkyToPlanar(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0])) {
  376.                                     FreeVec(DCTVcolors);
  377.                                     freecolors(pic->ilbm);
  378.                                     FreeArray();
  379.                                     FreeVec(p[0]);
  380.                                     FreeVec(p[1]);
  381.                                     FreeVec(p[2]);
  382.                                     CloseProgressWindow();
  383.                                     FreeDCTVCvt(handle);
  384.                                     return TRUE;
  385.                                 }
  386.                                 else {
  387.                                     e = "Unable to allocate memory for bitmap";
  388.                                     hnum = HE_AllocPlanes;
  389.                                 }
  390.                             }
  391.                             else {
  392.                                 e = "Unable to allocate memory for bitmap";
  393.                                 hnum = HE_AllocPlanes;
  394.                             }
  395.                             FreeArray();
  396.                             if (handle) {
  397.                                 FreeDCTVCvt(handle);
  398.                             }
  399.                             if (p[0]) FreeVec(p[0]);
  400.                             if (p[1]) FreeVec(p[1]);
  401.                             if (p[2]) FreeVec(p[2]);
  402.                         }
  403.                         else {
  404.                             e = "Unable to allocate memory for bitmap";
  405.                             hnum = HE_AllocPlanes;
  406.                         }
  407.                         FreeVec(DCTVcolors);
  408.                     }
  409.                     else {
  410.                         // not 24 bit and not DCTV
  411.                         // Convert image planar to screen palette planar (using 020+ if present)
  412.                         if (InitArray(pic->ilbm->Bmhd.w)) {
  413.                             if (ProgressWnd) {
  414.                               GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  415.                                                          GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  416.                                 HandleProgressIDCMP();
  417.                             }
  418.                             InitRastPort(&Rp);
  419.                             Rp.BitMap = pic->ilbm->brbitmap;
  420.                             maxcol = min(maxcol,1<<pic->ilbm->Bmhd.nPlanes);
  421.                             if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  422.                                 PaletteToScreen020(&Rp,pic,maxcol,r,g,b);
  423.                             }
  424.                              else {
  425.                                 PaletteToScreen000(&Rp,pic,maxcol,r,g,b);
  426.                             }
  427.                             // and clean up
  428.                             FreeArray();
  429.                             freecolors(pic->ilbm);
  430.                             CloseProgressWindow();
  431.                             return TRUE;
  432.                         }
  433.                         else {
  434.                             e = "Unable to allocate memory for bitmap";
  435.                             hnum = HE_AllocPlanes;
  436.                         }
  437.                     }
  438.                 }
  439.             }
  440.         }
  441.         else {
  442.             e = "Unable to AllocIFF";
  443.             hnum = HE_AllocIFF;
  444.         }
  445.     }
  446.     // If we are not opening OPAL and the file is not IFF
  447.    if ((OpenMode != OPEN_OPAL) &&
  448.          (FileFormat != FORMAT_IFF)) {
  449.        // if the screen is < 8 colours or we do not allow palette changes or image is not JPEG then
  450.        // we will remap later. Otherwise the JPEG code will code will use its own palette
  451.         if ((TSMorphWnd->WScreen->BitMap.Depth < 3) || (FileFormat != FORMAT_JPEG) ||
  452.             (!PaletteAllowed)) {
  453.             ReMap = TRUE;
  454.         }
  455.         if (ProgressWnd) {
  456.            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  457.                                   GTTX_Text,
  458.                                   (FileFormat == FORMAT_JPEG)?(ULONG)"Loading JFIF":
  459.                                   (FileFormat == FORMAT_GIF)?(ULONG)"Loading GIF":
  460.                                   (FileFormat == FORMAT_PPM)?(ULONG)"Loading PPM":
  461.                                   (FileFormat == FORMAT_TARGA)?(ULONG)"Loading Targa?":
  462.                                   (ULONG)"Loading ?",
  463.                                 TAG_END);
  464.             HandleProgressIDCMP();
  465.         }
  466.         // try and Load image (JFIF,GIF,PPM,TARGA)
  467.         if ((info = LoadJPEG(filename,ReMap?0:min(1<<TSMorphWnd->WScreen->BitMap.Depth,256),r,g,b,&(p[0]))) &&
  468.             ((info->output_file) || (p[0] && p[1] && p[2]))) {
  469.            if (info->output_file) {
  470.                p[0] = (UBYTE *)info->output_file;
  471.                p[1] = p[0] + (((info->image_width+15)>>4)<<4) * info->image_height;
  472.                p[2] = p[1] + (((info->image_width+15)>>4)<<4) * info->image_height;
  473.            }
  474.             // Allocate BitMap
  475.             if (ProgressWnd) {
  476.                GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  477.                                       GTTX_Text,(ULONG)"Allocating Bitmap",
  478.                                     TAG_END);
  479.                 HandleProgressIDCMP();
  480.             }
  481.             pic->ilbm->Bmhd.nPlanes = min(TSMorphWnd->WScreen->BitMap.Depth,8);
  482.             pic->ilbm->Bmhd.w = info->image_width;
  483.             pic->ilbm->Bmhd.h = info->image_height;
  484.             if (InitArray(pic->ilbm->Bmhd.w) && (pic->ilbm->brbitmap = AllocMem(sizeof(struct BitMap),MEMF_CLEAR))) {
  485.                 InitBitMap(pic->ilbm->brbitmap,pic->ilbm->Bmhd.nPlanes,info->image_width,info->image_height);
  486.                 for (i=0;
  487.                     (i < pic->ilbm->Bmhd.nPlanes) && !e;            // Allow up to 8 bitplanes
  488.                     ++i) {
  489.                     if (!(pic->ilbm->brbitmap->Planes[i] = AllocRaster(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h))) {
  490.                         e = "Unable to allocate memory for bitmap";
  491.                         hnum = HE_AllocPlanes;
  492.                     }
  493.                 }
  494.             }
  495.             else {
  496.                 e = "Unable to allocate memory for bitmap";
  497.                 hnum = HE_AllocPlanes;
  498.             }
  499.             if (!e) {
  500.                 if (ProgressWnd) {
  501.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  502.                                           GTTX_Text,(ULONG)"Converting to Planar",
  503.                                         TAG_END);
  504.                     HandleProgressIDCMP();
  505.                  }
  506.                  // Remap the RGB image to screen palette if required (see above)
  507.                  if (ReMap) {
  508.                     xadd = (((info->image_width+15)>>4)<<4) - info->image_width;
  509.                     red = p[0];
  510.                     blue = p[2];
  511.                     green = p[1];
  512.                     if (ProgressWnd) {
  513.                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  514.                                                GTTX_Text,(ULONG)"Remapping palette",
  515.                                               TAG_END);
  516.                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  517.                                              GTSL_Level,0,
  518.                                               GTSL_Max,info->image_height-1,TAG_END);
  519.                         HandleProgressIDCMP();
  520.                      }
  521.                     if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  522.                         RGBToScreen020(red,green,blue,info->image_height,info->image_width,maxcol,xadd,r,g,b);
  523.                     }
  524.                      else {
  525.                         RGBToScreen000(red,green,blue,info->image_height,info->image_width,maxcol,xadd,r,g,b);
  526.                     }
  527.                 }
  528.                 if (ProgressWnd) {
  529.                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  530.                                             GTTX_Text,(ULONG)"Converting to Planar",
  531.                                            TAG_END);
  532.                     HandleProgressIDCMP();
  533.                 }
  534.                 // Then convert back to planar
  535.                 if (ChunkyToPlanar(pic,info->image_width,info->image_height,p[0])) {
  536.                     if (!ReMap) {
  537.                         // not remapping so reformat JPEGs palette to our format
  538.                         if (ProgressWnd) {
  539.                            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  540.                                                   GTTX_Text,(ULONG)"Creating Colormap",
  541.                                                 TAG_END);
  542.                             HandleProgressIDCMP();
  543.                         }
  544.                         if (pic->ilbm->colortable = (Color4 *)AllocMem(min(1<<TSMorphWnd->WScreen->BitMap.Depth,256)*sizeof(Color4),NULL)) {
  545.                             pic->ilbm->ncolors = min(1<<TSMorphWnd->WScreen->BitMap.Depth,256);
  546.                             pic->ilbm->ctabsize = pic->ilbm->ncolors*sizeof(Color4);
  547.                             for (i = 0;
  548.                                  i < pic->ilbm->ncolors;
  549.                                  ++i) {
  550.                                 pic->ilbm->colortable[i] = ((r[i] & 0xf0) << 4) | (g[i] & 0xf0) | (b[i] >> 4);
  551.                             }
  552.                         }
  553.                     }
  554.                     // Free everything and return OK
  555.                     FreeArray();
  556.                     FreeVec(p[0]);
  557.                     CloseProgressWindow();
  558.                     return TRUE;
  559.                 }
  560.                 else {
  561.                     e = "Unable to allocate memory for bitmap";
  562.                     hnum = HE_AllocPlanes;
  563.                 }
  564.                 // Free everything
  565.             }
  566.             FreeArray();
  567.             if (pic->ilbm->brbitmap) {
  568.                 for (i = 0;
  569.                       (i < pic->ilbm->Bmhd.nPlanes);            // Allow up to 8 bitplanes
  570.                       ++i) {
  571.                     if (!(pic->ilbm->brbitmap->Planes[i])) {
  572.                         FreeRaster(pic->ilbm->brbitmap->Planes[i],pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  573.                         pic->ilbm->brbitmap->Planes[i] = NULL;
  574.                     }
  575.                 }
  576.                 FreeMem(pic->ilbm->brbitmap,sizeof(struct BitMap));
  577.                 pic->ilbm->brbitmap = NULL;
  578.             }
  579.             FreeVec(p[0]);
  580.         }
  581.     }
  582.     // If we have not hit a fatal error yet, and opal.library is available then try it
  583.     if (!e && OpalBase) {
  584.         if (ProgressWnd) {
  585.              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  586.                                  GTTX_Text,(ULONG)"Loading using opal.library",
  587.                                 TAG_END);
  588.             HandleProgressIDCMP();
  589.         }
  590.         Err = LoadImage24(NULL,filename,VIRTUALSCREEN24|FORCE24);
  591.         if (Err < OL_ERR_MAXERR) {
  592.             switch (Err) {
  593.             case OL_ERR_OUTOFMEM:
  594.                 e = "Failure - Out of memory - loading '%s'";
  595.                 break;
  596.             case OL_ERR_OPENFILE:
  597.                 e = "Failure - Opening file - loading '%s'";
  598.                 break;
  599.             case OL_ERR_FORMATUNKNOWN:
  600.                 e = "Failure - Unknown Format - loading '%s'";
  601.                 break;
  602.             case OL_ERR_NOTILBM:
  603.                 e = "Failure - Not an ILBM file - loading '%s'";
  604.                 break;
  605.             case OL_ERR_FILEREAD:
  606.                 e = "Failure - Reading file - loading '%s'";
  607.                 break;
  608.             case OL_ERR_BADIFF:
  609.                 e = "Failure - Bad IFF Format - loading '%s'";
  610.                 break;
  611.             case OL_ERR_CANTCLOSE:
  612.                 e = "Failure - Can not Close - loading '%s'";
  613.                 break;
  614.             case OL_ERR_BADJPEG:
  615.                 e = "Failure - Bad JPEG Format - loading '%s'";
  616.                 break;
  617.             case OL_ERR_UNSUPPORTED:
  618.                 e = "Failure - Unsupported Format - loading '%s'";
  619.                 break;
  620.             case OL_ERR_CTRLC:
  621.             case OL_ERR_NOTHUMBNAIL:
  622.             case OL_ERR_OPENSCREEN:
  623.             case OL_ERR_FILEWRITE:
  624.             default:
  625.                 e = "Failure - Unknown problem - loading '%s'";
  626.                 break;
  627.             }
  628.             e1 = filename;
  629.             hnum = HE_OpalVision;
  630.         }
  631.         else {
  632.             if (ProgressWnd) {
  633.                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  634.                                      GTTX_Text,(ULONG)"Converting to RGB",
  635.                                     TAG_END);
  636.                 HandleProgressIDCMP();
  637.             }
  638.             OScrn = (struct OpalScreen *)Err;
  639.             // Allocate chunky bit maps
  640.             if ((p[0] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0)) &&
  641.                  (p[1] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0)) &&
  642.                  (p[2] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0))) {
  643.                 // Convert Opal vision screen to RGB
  644.                  OVtoRGB(OScrn,p,0,0,((OScrn->Width+15)>>4)<<4,OScrn->Height);
  645.                 if (ProgressWnd) {
  646.                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  647.                                          GTTX_Text,(ULONG)"Allocating Bitmap",
  648.                                         TAG_END);
  649.                     HandleProgressIDCMP();
  650.                 }
  651.                 pic->ilbm->Bmhd.nPlanes = min(TSMorphWnd->WScreen->BitMap.Depth,8);
  652.                 pic->ilbm->Bmhd.w = OScrn->Width;
  653.                 pic->ilbm->Bmhd.h = OScrn->Height;
  654.                 // Allocate BitMap
  655.                 if (InitArray(pic->ilbm->Bmhd.w) && (pic->ilbm->brbitmap = AllocMem(sizeof(struct BitMap),MEMF_CLEAR))) {
  656.                     InitBitMap(pic->ilbm->brbitmap,pic->ilbm->Bmhd.nPlanes,OScrn->Width,OScrn->Height);
  657.                     for (i=0;
  658.                         (i < pic->ilbm->Bmhd.nPlanes) && !e;            // Allow up to 8 bitplanes
  659.                         ++i) {
  660.                         if (!(pic->ilbm->brbitmap->Planes[i] = AllocRaster(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h))) {
  661.                             e = "Unable to allocate memory for bitmap";
  662.                             hnum = HE_AllocPlanes;
  663.                         }
  664.                     }
  665.                 }
  666.                 else {
  667.                     e = "Unable to allocate memory for bitmap";
  668.                     hnum = HE_AllocPlanes;
  669.                 }
  670.                 // remap to screen palette and convert to planar - see above
  671.                 if (!e) {
  672.                     xadd = (((OScrn->Width+15)>>4)<<4) - OScrn->Width;
  673.                     red = p[0];
  674.                     blue = p[2];
  675.                     green = p[1];
  676.                     if (ProgressWnd) {
  677.                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  678.                                                GTTX_Text,(ULONG)"Remapping OPAL palette",
  679.                                               TAG_END);
  680.                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  681.                                              GTSL_Level,0,
  682.                                               GTSL_Max,OScrn->Height-1,TAG_END);
  683.                         HandleProgressIDCMP();
  684.                      }
  685.                     if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  686.                         RGBToScreen020(red,green,blue,OScrn->Height,OScrn->Width,maxcol,xadd,r,g,b);
  687.                     }
  688.                      else {
  689.                         RGBToScreen000(red,green,blue,OScrn->Height,OScrn->Width,maxcol,xadd,r,g,b);
  690.                     }
  691.                     if (ProgressWnd) {
  692.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  693.                                              GTTX_Text,(ULONG)"Converting to Planar",
  694.                                             TAG_END);
  695.                         HandleProgressIDCMP();
  696.                     }
  697.                     if (!ChunkyToPlanar(pic,OScrn->Width,OScrn->Height,p[0])) {
  698.                         e = "Unable to allocate memory for bitmap";
  699.                         hnum = HE_AllocPlanes;
  700.                     }
  701.                     // Free everything and return
  702.                 }
  703.                 else {
  704.                     if (pic->ilbm->brbitmap) {
  705.                         for (i = 0;
  706.                               (i < pic->ilbm->Bmhd.nPlanes);            // Allow up to 8 bitplanes
  707.                               ++i) {
  708.                             if (!(pic->ilbm->brbitmap->Planes[i])) {
  709.                                 FreeRaster(pic->ilbm->brbitmap->Planes[i],pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  710.                                 pic->ilbm->brbitmap->Planes[i] = NULL;
  711.                             }
  712.                         }
  713.                         FreeMem(pic->ilbm->brbitmap,sizeof(struct BitMap));
  714.                         pic->ilbm->brbitmap = NULL;
  715.                     }
  716.                 }
  717.                 FreeArray();
  718.             }
  719.             else {
  720.                 e = "Unable to allocate memory for bitmap";
  721.                 hnum = HE_AllocPlanes;
  722.             }
  723.             if (ProgressWnd) {
  724.                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  725.                                       GTTX_Text,(ULONG)"Cleaning up",
  726.                                      TAG_END);
  727.                 HandleProgressIDCMP();
  728.             }
  729.             if (p[0]) FreeVec(p[0]);
  730.            if (p[1]) FreeVec(p[1]);
  731.               if (p[2]) FreeVec(p[2]);
  732.             FreeScreen24(OScrn);
  733.             if (!e) {
  734.                 pic->Opal = TRUE;
  735.                 CloseProgressWindow();
  736.                 return TRUE;
  737.             }
  738.         }
  739.     }
  740.     else {
  741.         if (!e) {
  742.             e = "No opal.library";
  743.             hnum = HE_NoOpal;
  744.         }
  745.     }
  746.     // display error and return
  747.     Error(e,"OK",e1,hnum);
  748.     CloseProgressWindow();
  749.     return FALSE;
  750. }
  751.  
  752. extern struct RastPort     RP={0},            // Work Rast Ports
  753.                                  TRP={0};
  754. extern struct BitMap TBM={0};                // Temp bitmap
  755. extern UBYTE *plane0=NULL;                    // Planes for temporary bit maps
  756. extern UBYTE *plane1=NULL;
  757. extern UBYTE *plane2=NULL;
  758. extern UBYTE *plane3=NULL;
  759. extern UBYTE *plane4=NULL;
  760. extern UBYTE *plane5=NULL;
  761. extern UBYTE *plane6=NULL;
  762. extern UBYTE *plane7=NULL;
  763. extern UBYTE *Array=NULL;
  764.  
  765. /* Allocate and initialise things for image conversion
  766.  * w : width of image
  767.  */
  768. BOOL
  769. InitArray(UWORD w) {
  770.     if ((plane0 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  771.           (plane1 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  772.           (plane2 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  773.           (plane3 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  774.           (plane4 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  775.           (plane5 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  776.           (plane6 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  777.           (plane7 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  778.           (Array = AllocVec((((w+15)>>4)<<4),MEMF_CLEAR))) {
  779.          InitRastPort(&RP);
  780.       InitRastPort(&TRP);
  781.       InitBitMap(&TBM,8,w,1);
  782.       TRP.BitMap = &TBM;
  783.       TBM.Planes[0]=plane0;
  784.       TBM.Planes[1]=plane1;
  785.          TBM.Planes[2]=plane2;
  786.          TBM.Planes[3]=plane3;
  787.       TBM.Planes[4]=plane4;
  788.       TBM.Planes[5]=plane5;
  789.       TBM.Planes[6]=plane6;
  790.          TBM.Planes[7]=plane7;
  791.         return TRUE;
  792.     }
  793.     FreeArray();
  794.     return FALSE;
  795. }
  796.  
  797. /* Free everything allocated
  798.  * by InitArray()
  799.  */
  800. void
  801. FreeArray(void) {
  802.      if (plane0) {
  803.          FreeVec(plane0);
  804.          plane0 = NULL;
  805.      }
  806.    if (plane1) {
  807.        FreeVec(plane1);
  808.        plane1 = NULL;
  809.    }
  810.    if (plane2) {
  811.        FreeVec(plane2);
  812.        plane2 = NULL;
  813.    }
  814.    if (plane3) {
  815.        FreeVec(plane3);
  816.        plane3 = NULL;
  817.    }
  818.    if (plane4) {
  819.        FreeVec(plane4);
  820.        plane4 = NULL;
  821.    }
  822.    if (plane5) {
  823.        FreeVec(plane5);
  824.        plane5 = NULL;
  825.    }
  826.    if (plane6) {
  827.        FreeVec(plane6);
  828.        plane6 = NULL;
  829.    }
  830.    if (plane7) {
  831.        FreeVec(plane7);
  832.        plane7 = NULL;
  833.    }
  834.    if (Array) {
  835.        FreeVec(Array);
  836.        Array = NULL;
  837.    }
  838. }
  839.  
  840. /* Convert Chunky 8 bit to planar
  841.  * Always return true (historical)
  842.  * pic    - picture pointer
  843.  * w      - width
  844.  * h      - height
  845.  * chunky - chunky plane
  846.  */
  847. BOOL
  848. ChunkyToPlanar(struct Picture *pic,UWORD w,UWORD h,UBYTE *chunky) {
  849.       RP.BitMap = pic->ilbm->brbitmap;
  850.      WritePixelArray8(&RP,0,0,w-1,h-1,chunky,&TRP);
  851.      return TRUE;
  852. }
  853. /* Convert 24 bit chunky to RGB planar
  854.  * Always return true (historical)
  855.  * pic    - picture pointer
  856.  * w      - width
  857.  * h      - height
  858.  * r,g,b  - chunky pointers
  859.  */
  860. BOOL
  861. PlanarToChunky(struct Picture *pic,UWORD w,UWORD h,UBYTE *r,UBYTE *g,UBYTE *b) {
  862.     struct BitMap         BM;
  863.    InitBitMap(&BM,8,w,h);
  864.       RP.BitMap = &BM;
  865.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[0];
  866.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[1];
  867.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[2];
  868.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[3];
  869.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[4];
  870.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[5];
  871.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[6];
  872.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[7];
  873.    // Convert red to chunky
  874.    ReadPixelArray8(&RP,0,0,w-1,h-1,r,&TRP);
  875.    WaitBlit();
  876.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[8];
  877.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[9];
  878.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[10];
  879.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[11];
  880.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[12];
  881.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[13];
  882.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[14];
  883.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[15];
  884.    // and green
  885.    ReadPixelArray8(&RP,0,0,w-1,h-1,g,&TRP);
  886.    WaitBlit();
  887.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[16];
  888.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[17];
  889.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[18];
  890.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[19];
  891.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[20];
  892.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[21];
  893.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[22];
  894.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[23];
  895.    // and blue
  896.    ReadPixelArray8(&RP,0,0,w-1,h-1,b,&TRP);
  897.    WaitBlit();
  898.    return TRUE;
  899. }
  900.  
  901. /* RGB to screen palette
  902.  * 68000/010 version
  903.  * red,green,blue : chunky pointers - result is pallete mapped chunky in red
  904.  * Height,Width   : image size
  905.  * maxcol         : number of colours
  906.  * xadd           : skip at end of line
  907.  * r,g,b          : r,g,b palette
  908.  */
  909. void
  910. RGBToScreen000(UBYTE *red,UBYTE *green,UBYTE *blue,UWORD Height,UWORD Width,
  911.                           UWORD maxcol,UWORD xadd,UBYTE *r,UBYTE *g,UBYTE *b) {
  912.     UWORD i,j,k;
  913.     ULONG maxdiff;
  914.     ULONG diff;
  915.     LONG     t;
  916.     UWORD index;
  917.  
  918.     // for each line
  919.     for (j = 0;
  920.           j < Height;
  921.           ++j) {
  922.         if (ProgressWnd) {
  923.           GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  924.                                      GTSL_Level,(ULONG)j,TAG_END);
  925.             HandleProgressIDCMP();
  926.        }
  927.        // for each pixel
  928.         for (i = 0;
  929.               i < Width;
  930.               ++i) {
  931.             // Find closest color based on:
  932.             // red_difference*sqrt(3)+green_difference*srqt(6)+blue_difference
  933.             // (some sort of logic in the figures somewhere)
  934.             maxdiff = 0x7FFFFFFF;
  935.             for (k = 0;
  936.                   k < maxcol;
  937.                   ++k) {
  938.                 t = *red - r[k];
  939.                 diff = t*t*3;
  940.                 t = *green - g[k];
  941.                 diff += (t*t*6);
  942.                 t = *blue - b[k];
  943.                 diff += (t*t);
  944.                 if (diff < maxdiff) {
  945.                     maxdiff = diff;
  946.                     index = k;
  947.                 }
  948.             }
  949.             // Store index to color
  950.             *red = index;
  951.             ++red;
  952.             ++green;
  953.             ++blue;
  954.         }
  955.         red += xadd;
  956.         green += xadd;
  957.         blue += xadd;
  958.         if (ProgressWnd) {
  959.             HandleProgressIDCMP();
  960.         }
  961.     }
  962. }
  963.  
  964. /* Palette to screen palette
  965.  * 68000/010 version
  966.  * Rp    : work rast port
  967.  * pic   : picture pointer
  968.  * maxcol: number of colours
  969.  * r,g,b : r,g,b palette
  970.  */
  971. void
  972. PaletteToScreen000(struct RastPort *Rp,struct Picture *pic,UWORD maxcol,
  973.                                 UBYTE *r,UBYTE *g,UBYTE *b) {
  974.     UWORD    i,j,k;            // loop counters
  975.     LONG    penno;
  976.     UBYTE    rr,gg,bb;
  977.     ULONG maxdiff;
  978.     ULONG diff;
  979.     UWORD index;
  980.     LONG    t;                    // temp diff
  981.     UWORD EHB;
  982.     BOOL isHAM6 = FALSE;
  983.     BOOL isHAM8 = FALSE;
  984.     BOOL isEHB = FALSE;
  985.     struct DisplayInfo queryinfo;
  986.     DisplayInfoHandle handle;
  987.     struct BitMap         BM;
  988.     UBYTE *arrayp;
  989.  
  990.     // Initialise stuff
  991.    InitBitMap(&BM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  992.       RP.BitMap = &BM;
  993.    InitBitMap(&TBM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,1);
  994.    TRP.BitMap = &TBM;
  995.    TBM.Planes[0]=plane0;
  996.    TBM.Planes[1]=plane1;
  997.    TBM.Planes[2]=plane2;
  998.       TBM.Planes[3]=plane3;
  999.    TBM.Planes[4]=plane4;
  1000.    TBM.Planes[5]=plane5;
  1001.    TBM.Planes[6]=plane6;
  1002.    TBM.Planes[7]=plane7;
  1003.  
  1004.     // based on CAMG chunk determine special type of image
  1005.     if ((handle = FindDisplayInfo(pic->ilbm->camg)) &&
  1006.          (GetDisplayInfoData(handle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
  1007.         // 6 plane HAM
  1008.         if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1009.            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1010.                                      GTTX_Text,(ULONG)"Remapping HAM6 palette",
  1011.                                     TAG_END);
  1012.             isHAM6 = TRUE;
  1013.         }
  1014.         else {
  1015.             // 8 plane HAM
  1016.             if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1017.                 isHAM8 = TRUE;
  1018.                GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1019.                                      GTTX_Text,(ULONG)"Remapping HAM8 palette",
  1020.                                     TAG_END);
  1021.             }
  1022.             else {
  1023.                 // 6 plane EHB
  1024.                   if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
  1025.                       isEHB = TRUE;
  1026.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1027.                                                    GTTX_Text,(ULONG)"Remapping EHB palette",
  1028.                                                 TAG_END);
  1029.                   }
  1030.                   else {
  1031.                       // standard ILBM
  1032.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1033.                                               GTTX_Text,(ULONG)"Remapping ILBM palette",
  1034.                                             TAG_END);
  1035.                   }
  1036.             }
  1037.         }
  1038.     }
  1039.     // for each line
  1040.     for (j = 0;
  1041.          j < pic->ilbm->Bmhd.h;
  1042.          ++j) {
  1043.         if (ProgressWnd) {
  1044.           GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  1045.                               GTSL_Level,(ULONG)j,TAG_END);
  1046.             HandleProgressIDCMP();
  1047.           }
  1048.           // convert line to chunky
  1049.           ReadPixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
  1050.           arrayp = Array;
  1051.           // for each pixel depending on mode convert line to screen palette (like palette to screen)
  1052.         if (isHAM6) {
  1053.             // rgb = 0 at start of line
  1054.               rr = gg = bb = 0;
  1055.            for (i = 0;
  1056.                     i < pic->ilbm->Bmhd.w;
  1057.                  ++i) {
  1058.                penno = *arrayp;
  1059.                switch (penno & 0x30) {    // HAM selection
  1060.                case 0:
  1061.                    rr = pic->ilbm->RGB[penno*4+1];
  1062.                    gg = pic->ilbm->RGB[penno*4+2];
  1063.                    bb = pic->ilbm->RGB[penno*4+3];
  1064.                    break;
  1065.                case 0x10:
  1066.                    bb = (penno&0xf)|((penno&0xf)<<4);
  1067.                    break;
  1068.                case 0x20:
  1069.                    rr = (penno&0xf)|((penno&0xf)<<4);
  1070.                    break;
  1071.                case 0x30:
  1072.                    gg = (penno&0xf)|((penno&0xf)<<4);
  1073.                    break;
  1074.                }
  1075.                 // Find closest color
  1076.                 maxdiff = 0x7FFFFFFF;
  1077.                 for (k = 0;
  1078.                       k < maxcol;
  1079.                       ++k) {
  1080.                     t = rr - r[k];
  1081.                     diff = t*t*3;
  1082.                     t = gg - g[k];
  1083.                     diff += (t*t*6);
  1084.                     t = bb - b[k];
  1085.                     diff += (t*t);
  1086.                     if (diff < maxdiff) {
  1087.                         maxdiff = diff;
  1088.                         index = k;
  1089.                     }
  1090.                 }
  1091.                 *arrayp++ = index;
  1092.             }
  1093.           }
  1094.           else {
  1095.               if (isHAM8) {
  1096.                   // very similar to HAM6
  1097.                 rr = gg = bb = 0;
  1098.                for (i = 0;
  1099.                         i < pic->ilbm->Bmhd.w;
  1100.                      ++i) {
  1101.                    penno = *arrayp;
  1102.                    switch (penno & 0xc0) {
  1103.                    case 0:
  1104.                        rr = pic->ilbm->RGB[penno*4+1];
  1105.                        gg = pic->ilbm->RGB[penno*4+2];
  1106.                        bb = pic->ilbm->RGB[penno*4+3];
  1107.                        break;
  1108.                    case 0x40:
  1109.                        bb = (penno&0x3f)<<2;
  1110.                        break;
  1111.                    case 0x80:
  1112.                        rr = (penno&0x3f)<<2;
  1113.                        break;
  1114.                    case 0xc0:
  1115.                        gg = (penno&0x3f)<<2;
  1116.                        break;
  1117.                    }
  1118.                     // Find closest color
  1119.                     maxdiff = 0x7FFFFFFF;
  1120.                     for (k = 0;
  1121.                           k < maxcol;
  1122.                           ++k) {
  1123.                         t = rr - r[k];
  1124.                         diff = t*t*3;
  1125.                         t = gg - g[k];
  1126.                         diff += (t*t*6);
  1127.                         t = bb - b[k];
  1128.                         diff += (t*t);
  1129.                         if (diff < maxdiff) {
  1130.                             maxdiff = diff;
  1131.                             index = k;
  1132.                         }
  1133.                     }
  1134.                     *arrayp++ = index;
  1135.                 }
  1136.               }
  1137.               else {
  1138.                   if (isEHB) {
  1139.                       // simple - just check highest plane and divide by two if required
  1140.                    for (i = 0;
  1141.                             i < pic->ilbm->Bmhd.w;
  1142.                          ++i) {
  1143.                        penno = *arrayp;
  1144.                        EHB = (penno & 0x20)?1:0;
  1145.                        penno &= 0x1f;
  1146.                        rr = pic->ilbm->RGB[penno*4+1]>>EHB;
  1147.                        gg = pic->ilbm->RGB[penno*4+2]>>EHB;
  1148.                        bb = pic->ilbm->RGB[penno*4+3]>>EHB;
  1149.                         // Find closest color
  1150.                         maxdiff = 0x7FFFFFFF;
  1151.                         for (k = 0;
  1152.                               k < maxcol;
  1153.                               ++k) {
  1154.                             t = rr - r[k];
  1155.                             diff = t*t*3;
  1156.                             t = gg - g[k];
  1157.                             diff += (t*t*6);
  1158.                             t = bb - b[k];
  1159.                             diff += (t*t);
  1160.                             if (diff < maxdiff) {
  1161.                                 maxdiff = diff;
  1162.                                 index = k;
  1163.                             }
  1164.                         }
  1165.                         *arrayp++ = index;
  1166.                     }
  1167.                   }
  1168.                   else {
  1169.                       // simple palette remap
  1170.                    for (i = 0;
  1171.                             i < pic->ilbm->Bmhd.w;
  1172.                          ++i) {
  1173.                        penno = *arrayp;
  1174.                        rr = pic->ilbm->RGB[penno*4+1];
  1175.                        gg = pic->ilbm->RGB[penno*4+2];
  1176.                        bb = pic->ilbm->RGB[penno*4+3];
  1177.                         // Find closest color
  1178.                         maxdiff = 0x7FFFFFFF;
  1179.                         for (k = 0;
  1180.                               k < maxcol;
  1181.                               ++k) {
  1182.                             t = rr - r[k];
  1183.                             diff = t*t*3;
  1184.                             t = gg - g[k];
  1185.                             diff += (t*t*6);
  1186.                             t = bb - b[k];
  1187.                             diff += (t*t);
  1188.                             if (diff < maxdiff) {
  1189.                                 maxdiff = diff;
  1190.                                 index = k;
  1191.                             }
  1192.                         }
  1193.                         *arrayp++ = index;
  1194.                     }
  1195.                 }
  1196.             }
  1197.        }
  1198.        // Convert line from chunky palette to planar
  1199.        WritePixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
  1200.     }
  1201. }
  1202.